package la.iok.hzsvn.lewin.movie.service;

import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.movieservice.vo.MovieLevelVo;
import la.iok.hzsvn.lewin.movie.entity.HolidayConfig;
import la.iok.hzsvn.lewin.movie.entity.MovieLevel;
import la.iok.hzsvn.lewin.movie.mapper.MovieLevelMapper;
import la.iok.hzsvn.lewin.movie.model.MovieLevelParam;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.Nullable;
import la.iok.hzsvn.share.tools.datetime.DateTimeUtil;
import la.iok.hzsvn.share.utils.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovieLevelServiceImpl extends BaseServiceImpl<MovieLevel, MovieLevelMapper,Long> implements MovieLevelService {
    private final HolidayConfigService holidayConfigService;
    public MovieLevelServiceImpl(MovieLevelMapper mapper, HolidayConfigService holidayConfigService) {
        super(mapper);
        this.holidayConfigService = holidayConfigService;
    }
    @Override
    public void delete(@NotNull Token token, @Nullable Long id) {
        if(id == null){
            return;
        }
        ErrorCode.ADMIN_DENIED.assertTrue(token.hasAuthority(RoleEnum.Admin));
        delete(id);
    }

    @Override
    public Long save(@NotNull Token token, @NotNull MovieLevelParam param) {
        String name = validateParam(token, param);
        ErrorCode.PROPERTY_CHECK_ERROR.assertNull(select("name",name),"名称","此名称的记录已经存在");
        ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(param.getReturnMoneySupport(),
                new Integer[]{MovieLevel.RETURN_MONEY_SUPPORT, MovieLevel.RETURN_MONEY_UNSUPPORTED},"返利","值只能是0或者1");
        if(param.getEnableHolidayPrice() != null){
            ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(param.getEnableHolidayPrice(),
                    new Integer[]{MovieLevel.DISABLE_HOLIDAY_PRICE, MovieLevel.ENABLE_HOLIDAY_PRICE},"假期价格","值只能是0或者1");
        }
        MovieLevel level = new MovieLevel();
        level.setName(name);
        level.setPrice(param.getPrice());
        level.setOpenPrice(param.getOpenPrice());
        level.setReturnMoneySupport(param.getReturnMoneySupport());
        if(param.getEnableHolidayPrice() != null){
            level.setEnableHolidayPrice(param.getEnableHolidayPrice());
        }
        insertSelective(level);
        return level.getId();
    }

    @Transactional
    @Override
    public void update(@NotNull Token token, @NotNull Long id, @NotNull MovieLevelParam param) {
        String name = validateParam(token, param);
        ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(param.getReturnMoneySupport(),
                new Integer[]{MovieLevel.RETURN_MONEY_SUPPORT, MovieLevel.RETURN_MONEY_UNSUPPORTED},"返利","值只能是0或者1");
        if(param.getEnableHolidayPrice() != null){
            ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(param.getEnableHolidayPrice(),
                    new Integer[]{MovieLevel.DISABLE_HOLIDAY_PRICE, MovieLevel.ENABLE_HOLIDAY_PRICE},"假期价格","值只能是0或者1");
        }
        MovieLevel level = select(id);
        ErrorCode.RECORD_NOT_EXIST.assertNotNull(level,id);
        ErrorCode.RECORD_MODIFIED_ERROR.assertEqual(level.getVersion(),param.getVersion(),id);
        level.setName(name);
        level.setPrice(param.getPrice());
        level.setOpenPrice(param.getOpenPrice());
        level.setReturnMoneySupport(param.getReturnMoneySupport());
        if(param.getEnableHolidayPrice() != null){
            level.setEnableHolidayPrice(param.getEnableHolidayPrice());
        }
        ErrorCode.RECORD_MODIFIED_ERROR.assertEqual(1,mapper.update(level),id);
    }

    private String validateParam(@NotNull Token token, @NotNull MovieLevelParam param) {
        ErrorCode.ADMIN_DENIED.assertTrue(token.hasAuthority(RoleEnum.Admin));
        String name = ErrorCode.NAME_BLANK_ERROR.assertNotBlank(param.getName());
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getPrice(),"价格","不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(param.getPrice() >= 0,"价格","不能为负数");
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getOpenPrice(),"开本价格","不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(param.getOpenPrice() >= 0,"开本价格","不能为负数");
        return name;
    }

    @Override
    public List<MovieLevelVo> po2vo(Collection<MovieLevel> entities) {
        if(CollectionUtils.isEmpty(entities)){
            return Collections.emptyList();
        }
        HolidayConfig holiday = holidayConfigService.select(DateTimeUtil.safelyFormatDate(new Date(), "yyyy-MM-dd",null));
        return entities.stream().filter(Objects::nonNull).map(item->{
            MovieLevelVo vo = new MovieLevelVo();
            BeanUtils.copyProperties(item, vo);
            vo.setTodayPrice(vo.getOpenPrice());
            if(holiday != null && holiday.holiday()){
                if(vo.holidayEnabled() && vo.getOpenPrice() != null && vo.getOpenPrice() > 0){
                    vo.setTodayPrice(vo.getOpenPrice() + 2000); // 假期价格在原来价格基础上增加20元
                }
            }
            return vo;
        }).collect(Collectors.toList());
    }
}
